
const API_DOMAIN = 'https://api-cto.go8.workers.dev/p/'
const DB_HASH = "evlon-db-cdndb-p";
const DB_HASH_IV = "987123654456abcd";
const Ctoaes = require('./ctoaes');
const fetch = require('node-fetch');
class CtoM3u8{

    constructor(token){
        this._token = token;
    }

    async down_m3u8(uri){
        
        //m3u8 content
        let m3u8_resp = await fetch(uri,{
            headers:{
                authorization:this._token
            }
        })
        let m3u8content = await m3u8_resp.text();

        console.log(m3u8content);
        return m3u8content;
    }

    async replace_m3u8_uri_with_key(m3u8content, key){
        let ctoaes = new Ctoaes();
        let jsonObj = {
            p: key,
            t: new Date().valueOf()
        };

        let token = ctoaes.encryption_utf82hex(JSON.stringify(jsonObj), Buffer.from(DB_HASH, "utf8"), Buffer.from(DB_HASH_IV, "utf8"))

        m3u8content = m3u8content.replace(/#EXT-X-KEY:METHOD=(AES-128),URI="(.*?)"\s*,(\s*IV=0x[0-9a-fA-g]{32}\s*#)/i,
            ($0, $1, $2, $3) => {
                return '#EXT-X-KEY:METHOD=AES-128-ECB,URI="' + API_DOMAIN + encodeURIComponent(token) + '",' + $3;
            });

        return m3u8content;
    }

    async replace_m3u8_key(m3u8content, decodeKeyParam){

        //m3u8 key
        let m3u8pwdiv_regex = /#EXT-X-KEY:METHOD=AES-128,URI="(.*?)"\s*,\s*IV=0x([0-9a-fA-g]{32})\s*#/i;
        let matchs = m3u8pwdiv_regex.exec(m3u8content);
        if (!(matchs && matchs.length > 2)) {
            throw "m3u8 down error";             
        }
    
        // let keyiv = {
        //     keyuri: matchs[1],
        //     iv: matchs[2]
        // };
        let keyuri = matchs[1];
        //"https://b.edu.51cto.com/zyxy/video/play/key?id=174317&sign=e78e863975db5cc47b22d95e3a5ab7fd"
        //"/center/player/play/get-key?lesson_id=524828&id=423954&type=course&lesson_type=course&isPreview=0
        // let keyuri = urllib.resolve(m3u8url, keyiv.keyuri) + "&sign=" + sign;
        let keyuri_resp = await fetch(keyuri, {
            timeout: 50 * 1000,
            method: "GET",
            headers: {authorization:this._token}
        });

        //"NiVoszRzydtWkiQ5NlpNZTh4RFo4NzBFWmVHd2RNYmFmRE9hSXdUTTJBZU5qZGxibEdOTWMxY0RiTzIzNzVZMjI1ZE5tNDl4WTdXNVlReQ=="
        let keyuritext = await keyuri_resp.text();
        

        //let keyuritext = 'ZiGmsZDZyMxDZs0EZGwMDOIwTM2ANjllGNM1DO2YNmxYWYQy';

        let pwdBuff1 = Buffer.from(keyuritext, 'base64');

        // t = u.lib.WordArray.create(new Uint8Array(t)).toString(u.enc.Utf8),
        let pwdBuff2 = Buffer.from(Uint32Array.from(Uint8Array.from(pwdBuff1))).toString('base64')
        // let pwdBuff2 = pwdBuff1.toString('utf8');

        //t = h(t, a._lid.replace(/_\d*/, ""))
        // let lessonId = '388058';
        let pwdBuff3 = await decPwd(pwdBuff2, decodeKeyParam);

        //"dd1dc82069c86fad"
        let pwdBuff4 = pwdBuff3.replace(/_\d*/, "")
        console.log([keyuritext,pwdBuff1,pwdBuff2,pwdBuff3,pwdBuff4])
        if(pwdBuff4.length != 16){
            throw 'pwd decode error'
        }
           
        let ctoaes = new Ctoaes();
        let jsonObj = {
            p: pwdBuff4,
            t: new Date().valueOf()
        };

        let token = ctoaes.encryption_utf82hex(JSON.stringify(jsonObj), Buffer.from(DB_HASH, "utf8"), Buffer.from(DB_HASH_IV, "utf8"))

        m3u8content = m3u8content.replace(/#EXT-X-KEY:METHOD=(AES-128),URI="(.*?)"\s*,(\s*IV=0x[0-9a-fA-g]{32}\s*#)/i,
            ($0, $1, $2, $3) => {
                return '#EXT-X-KEY:METHOD=AES-128-ECB,URI="' + API_DOMAIN + encodeURIComponent(token) + '",' + $3;
            });


        //https://b.edu.51cto.com/zyxy/video/play/api?sign=e78e863975db5cc47b22d95e3a5ab7fd&lesson_id=174317
            
        return {
            content: m3u8content,
            pwd: pwdBuff4
        };
       

    }
}
async function decPwd(utfStr, lessonId) {
    let obje = {},
        objv = {};
    pwdlib(obje, objv);

    return objv.dec(utfStr, lessonId);

}

function pwdlib(e, v) {
    var s = ["s", "i", "y", "u", "a", "n", "t", "l", "w", "x"],
        o = [function (e) {
            return e
        }, function (e, t, r) {
            r = r || "eDu_51Cto_siyuanTlw";
            for (var i = v.base64decode(e).split(""), a = v.MD5(t + r).toString(), n = a.length - 1; 0 <= n; n--) {
                var s = a[n].charCodeAt() % (i.length - 1);
                i.splice(s, 1)
            }
            return i.join("")
        }, function (e, t, r) {
            for (var i = t % 7, a = e.length, n = "", s = 0; s < a / 2; s++) {
                var o = 2 * s;
                n += 0 == i || s % i == 0 ? e[o] + e[o + 1] : e[o + 1] ? e[o + 1] + e[o] : e[o]
            }
            var l = v.base64decode(n),
                u = (l.length - 1) / 2,
                d = "";
            for (s = 0; s < u; s++)
                o = 2 * s,
                i < s && o++,
                d += s % 3 == 0 ? l[o] : l[o + 1];
            return d
        }, function (e) {
            return e
        }, function (e) {
            return e
        }, function (e, t, r) {
            var i, a, n, s, o, l, u, d = e.slice(0, 7) + e.slice(10, 12) + e.slice(15, -3),
                c = "",
                h = 0,
                f = 0,
                p = "";
            d = d.split("").reverse().join(""),
                i = v.eeb64(d),
                a = parseInt(i.substr(0, 1)),
                s = (n = i.slice(6, -3)).match(/^\d*/),
                o = n.match(/\d*$/),
                l = s[0],
                u = o[0],
                n = n.replace(/^\d*/, "").replace(/\d*$/, "");
            for (var g = 0; g < u.length; g++)
                c += v.bu(parseInt(u[g]).toString(2), 3);
            for (c = c.substr(a),
                g = 0; g < c.length; g++)
                1 == c[g] ? (p += l[f],
                    f++) : (p += n[h],
                    h++);
            return p
        }, function (e, t, r) {
            for (var i, a = {
                    B: "0",
                    q: "1",
                    r: "2",
                    C: "3",
                    w: "4",
                    x: "5",
                    V: "6",
                    e: "7",
                    f: "8",
                    D: "9",
                    9: "a",
                    4: "b",
                    5: "c",
                    7: "d",
                    m: "e",
                    n: "f",
                    o: "g",
                    H: "h",
                    I: "i",
                    N: "j",
                    O: "k",
                    P: "l",
                    Q: "m",
                    R: "n",
                    S: "o",
                    U: "p",
                    X: "q",
                    L: "r",
                    M: "s",
                    a: "t",
                    b: "u",
                    F: "v",
                    c: "w",
                    d: "x",
                    g: "y",
                    h: "z",
                    i: "A",
                    j: "B",
                    y: "C",
                    z: "D",
                    k: "E",
                    l: "F",
                    6: "G",
                    G: "H",
                    A: "I",
                    p: "J",
                    s: "K",
                    t: "L",
                    u: "M",
                    J: "N",
                    K: "O",
                    v: "P",
                    W: "Q",
                    0: "R",
                    Y: "S",
                    Z: "T",
                    2: "U",
                    3: "V",
                    E: "W",
                    T: "X",
                    8: "Y",
                    1: "Z"
                }, n = 5, s = "", o = 0, l = "", u = 0, d = 0; d < e.length; d++) {
                var c = e[d];
                s += a[c] ? a[c] : c
            }
            for (d = 0; d < 8; d++)
                i = 7 == d ? 32 - u : Math.abs(8 - n++),
                l += s.substr(o++, 1),
                o += i,
                u += i;
            return l += s.substr(40),
                v.eeb64(l.split("").reverse().join(""))
        }, function (e, t, r) {
            r = r || "eDu_51Cto_siyuanTlw";
            var i = v.eeb64(e),
                a = v.MD5(r + t).toString().slice(0, 16),
                n = i.indexOf(a),
                s = parseInt(i.slice(0, n), 16);
            if (!n)
                return !1;
            var o = i.substr(16 + n);
            return o.length == s && o
        }];
    v.bu = function (e, t) {
            for (var r = t - (e += "").length; 0 < r; r--)
                e = "0" + e;
            return e
        },
        v.MD5 = function (e) {
            var t, a = 0,
                n = 8;

            function o(e, t, r, i, a, n) {
                return g((s = g(g(t, e), g(i, n))) << a | s >>> 32 - a, r);
                var s
            }

            function c(e, t, r, i, a, n, s) {
                return o(t & r | ~t & i, e, t, a, n, s)
            }

            function h(e, t, r, i, a, n, s) {
                return o(t & i | r & ~i, e, t, a, n, s)
            }

            function f(e, t, r, i, a, n, s) {
                return o(t ^ r ^ i, e, t, a, n, s)
            }

            function p(e, t, r, i, a, n, s) {
                return o(r ^ (t | ~i), e, t, a, n, s)
            }

            function g(e, t) {
                var r = (65535 & e) + (65535 & t);
                return (e >> 16) + (t >> 16) + (r >> 16) << 16 | 65535 & r
            }
            return function (e) {
                for (var t = a ? "0123456789ABCDEF" : "0123456789abcdef", r = "", i = 0; i < 4 * e.length; i++)
                    r += t.charAt(e[i >> 2] >> i % 4 * 8 + 4 & 15) + t.charAt(e[i >> 2] >> i % 4 * 8 & 15);
                return r
            }(function (e, t) {
                e[t >> 5] |= 128 << t % 32,
                    e[14 + (t + 64 >>> 9 << 4)] = t;
                for (var r = 1732584193, i = -271733879, a = -1732584194, n = 271733878, s = 0; s < e.length; s += 16) {
                    var o = r,
                        l = i,
                        u = a,
                        d = n;
                    i = p(i = p(i = p(i = p(i = f(i = f(i = f(i = f(i = h(i = h(i = h(i = h(i = c(i = c(i = c(i = c(i, a = c(a, n = c(n, r = c(r, i, a, n, e[s + 0], 7, -680876936), i, a, e[s + 1], 12, -389564586), r, i, e[s + 2], 17, 606105819), n, r, e[s + 3], 22, -1044525330), a = c(a, n = c(n, r = c(r, i, a, n, e[s + 4], 7, -176418897), i, a, e[s + 5], 12, 1200080426), r, i, e[s + 6], 17, -1473231341), n, r, e[s + 7], 22, -45705983), a = c(a, n = c(n, r = c(r, i, a, n, e[s + 8], 7, 1770035416), i, a, e[s + 9], 12, -1958414417), r, i, e[s + 10], 17, -42063), n, r, e[s + 11], 22, -1990404162), a = c(a, n = c(n, r = c(r, i, a, n, e[s + 12], 7, 1804603682), i, a, e[s + 13], 12, -40341101), r, i, e[s + 14], 17, -1502002290), n, r, e[s + 15], 22, 1236535329), a = h(a, n = h(n, r = h(r, i, a, n, e[s + 1], 5, -165796510), i, a, e[s + 6], 9, -1069501632), r, i, e[s + 11], 14, 643717713), n, r, e[s + 0], 20, -373897302), a = h(a, n = h(n, r = h(r, i, a, n, e[s + 5], 5, -701558691), i, a, e[s + 10], 9, 38016083), r, i, e[s + 15], 14, -660478335), n, r, e[s + 4], 20, -405537848), a = h(a, n = h(n, r = h(r, i, a, n, e[s + 9], 5, 568446438), i, a, e[s + 14], 9, -1019803690), r, i, e[s + 3], 14, -187363961), n, r, e[s + 8], 20, 1163531501), a = h(a, n = h(n, r = h(r, i, a, n, e[s + 13], 5, -1444681467), i, a, e[s + 2], 9, -51403784), r, i, e[s + 7], 14, 1735328473), n, r, e[s + 12], 20, -1926607734), a = f(a, n = f(n, r = f(r, i, a, n, e[s + 5], 4, -378558), i, a, e[s + 8], 11, -2022574463), r, i, e[s + 11], 16, 1839030562), n, r, e[s + 14], 23, -35309556), a = f(a, n = f(n, r = f(r, i, a, n, e[s + 1], 4, -1530992060), i, a, e[s + 4], 11, 1272893353), r, i, e[s + 7], 16, -155497632), n, r, e[s + 10], 23, -1094730640), a = f(a, n = f(n, r = f(r, i, a, n, e[s + 13], 4, 681279174), i, a, e[s + 0], 11, -358537222), r, i, e[s + 3], 16, -722521979), n, r, e[s + 6], 23, 76029189), a = f(a, n = f(n, r = f(r, i, a, n, e[s + 9], 4, -640364487), i, a, e[s + 12], 11, -421815835), r, i, e[s + 15], 16, 530742520), n, r, e[s + 2], 23, -995338651), a = p(a, n = p(n, r = p(r, i, a, n, e[s + 0], 6, -198630844), i, a, e[s + 7], 10, 1126891415), r, i, e[s + 14], 15, -1416354905), n, r, e[s + 5], 21, -57434055), a = p(a, n = p(n, r = p(r, i, a, n, e[s + 12], 6, 1700485571), i, a, e[s + 3], 10, -1894986606), r, i, e[s + 10], 15, -1051523), n, r, e[s + 1], 21, -2054922799), a = p(a, n = p(n, r = p(r, i, a, n, e[s + 8], 6, 1873313359), i, a, e[s + 15], 10, -30611744), r, i, e[s + 6], 15, -1560198380), n, r, e[s + 13], 21, 1309151649), a = p(a, n = p(n, r = p(r, i, a, n, e[s + 4], 6, -145523070), i, a, e[s + 11], 10, -1120210379), r, i, e[s + 2], 15, 718787259), n, r, e[s + 9], 21, -343485551),
                        r = g(r, o),
                        i = g(i, l),
                        a = g(a, u),
                        n = g(n, d)
                }
                return Array(r, i, a, n)
            }(function (e) {
                for (var t = Array(), r = (1 << n) - 1, i = 0; i < e.length * n; i += n)
                    t[i >> 5] |= (e.charCodeAt(i / n) & r) << i % 32;
                return t
            }(t = e), t.length * n))
        },
        v.eeb64 = function (e) {
            for (var t = "", r = "", i = 0; i < e.length; i++)
                t += v.bu("BqrCwxVefD9457mnoHINOPQRSUXLMabFcdghijyzkl6GApstuJKvW0YZ23ET81=_".indexOf(e[i]).toString(2), 6);
            for (t = t.substring(t.length % 8),
                i = 0; i < Math.ceil(t.length / 8); i++)
                r += String.fromCharCode(parseInt(t.substr(8 * i, 8), 2));
            return v.base64decode(r)
        },
        v.dec = function (e, t) {
            function r(e) {
                for (var t = 0; t < s.length; t++)
                    if (s[t] == e)
                        return t
            }
            e[1];
            var i = [o[r(e[13])], o[r(e[8])], o[r(e[4])]],
                a = e.substr(0, 1) + e.substr(2, 2) + e.substr(5, 3) + e.substr(9, 4) + e.substr(14);
            for (var n in i)
                a = i[n](a, t);
            return a
        },
        v.base64decode = function (e) {
            var t, r, i, a, n, s, o, l = new Array(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);
            for (s = e.length,
                n = 0,
                o = ""; n < s;) {
                for (; t = l[255 & e.charCodeAt(n++)],
                    n < s && -1 == t;)
                ;
                if (-1 == t)
                    break;
                for (; r = l[255 & e.charCodeAt(n++)],
                    n < s && -1 == r;)
                ;
                if (-1 == r)
                    break;
                o += String.fromCharCode(t << 2 | (48 & r) >> 4);
                do {
                    if (61 == (i = 255 & e.charCodeAt(n++)))
                        return o;
                    i = l[i]
                } while (n < s && -1 == i);
                if (-1 == i)
                    break;
                o += String.fromCharCode((15 & r) << 4 | (60 & i) >> 2);
                do {
                    if (61 == (a = 255 & e.charCodeAt(n++)))
                        return o;
                    a = l[a]
                } while (n < s && -1 == a);
                if (-1 == a)
                    break;
                o += String.fromCharCode((3 & i) << 6 | a)
            }
            return o
        },
        v.base64ToArrayBuffer = function (e) {
            for (var t = atob(e), r = t.length, i = new Uint8Array(r), a = 0; a < r; a++)
                i[a] = t.charCodeAt(a);
            return i.buffer
        },
        v.arrayBufferToBase64 = function (e) {
            for (var t = "", r = new Uint8Array(e), i = r.byteLength, a = 0; a < i; a++)
                t += String.fromCharCode(r[a]);
            return btoa(t)
        }
}

module.exports = CtoM3u8;